﻿Option Strict On
Imports Microsoft.VisualBasic
Imports System.Data
Imports System.Text
Imports System.Data.SqlClient
Imports System.Xml.Serialization
Imports System.Web.Security
Imports System.Text.RegularExpressions
Imports Newtonsoft.Json


#Region "用户通行证管理"
''' <summary>
''' 通行证管理器
''' </summary>
''' <remarks></remarks>
Public Class PassportManage
    Inherits ClsBase
    Private DSNName As String

    Public Function Login(ByVal UserName As String, ByVal Password As String, ByVal fnIPAddr As String, ByVal fnSessionId As String, ByRef mPassport As PassportInfo, Optional ByVal token As String = "") As Integer

        Dim DataBase As New Data.DataFactory(DSNName)
        '参数前缀
        Dim prefix As String = CStr(IIf(DataBase.IsMsSql(), "@", ""))

        'ID参数定义
        Dim IDPara As System.Data.Common.DbParameter = DataBase.CreateParameter()
        IDPara.ParameterName = String.Concat(prefix, "OutID")
        IDPara.Direction = ParameterDirection.Output
        IDPara.DbType = DbType.Int32
        IDPara.Size = 4
        IDPara.Value = 0

        'LoginUID参数定义
        Dim UIDPara As System.Data.Common.DbParameter = DataBase.CreateParameter()
        UIDPara.ParameterName = String.Concat(prefix, "LoginUID")
        UIDPara.DbType = DbType.String
        UIDPara.Value = UserName

        'LoginPWD参数定义
        Dim PWDPara As System.Data.Common.DbParameter = DataBase.CreateParameter()
        PWDPara.ParameterName = String.Concat(prefix, "LoginPWD")
        PWDPara.DbType = DbType.String
        PWDPara.Size = 30
        PWDPara.Value = Password

        'LoginIP参数定义
        Dim IPPara As System.Data.Common.DbParameter = DataBase.CreateParameter()
        IPPara.ParameterName = String.Concat(prefix, "LoginIP")
        IPPara.DbType = DbType.String
        IPPara.Size = 30
        IPPara.Value = fnIPAddr

        'SessionID参数定义
        Dim SessionPara As System.Data.Common.DbParameter = DataBase.CreateParameter()
        SessionPara.ParameterName = String.Concat(prefix, "SessionID")
        SessionPara.DbType = DbType.String
        SessionPara.Size = 100
        SessionPara.Value = fnSessionId

        'token参数定义
        Dim tokenPara As System.Data.Common.DbParameter = DataBase.CreateParameter()
        tokenPara.ParameterName = String.Concat(prefix, "token")
        tokenPara.DbType = DbType.String
        tokenPara.Size = 100
        tokenPara.Value = token


        '所有参数数组
        Dim Params As System.Data.Common.DbParameter()
        If DataBase.IsOracle Then
            Dim cursor As New System.Data.OracleClient.OracleParameter
            cursor.ParameterName = "p_cursor"
            cursor.OracleType = OracleClient.OracleType.Cursor
            cursor.Direction = ParameterDirection.Output
            Params = {IDPara, UIDPara, PWDPara, IPPara, SessionPara, tokenPara, cursor}
        Else
            Params = {IDPara, UIDPara, PWDPara, IPPara, SessionPara, tokenPara}
        End If
        Dim ErrCode As Integer
        Try

            Dim dsPassport As New DataSet("Passport")
            ErrCode = DataBase.ExecuteProduce("[sp_passportlogin]", Params, dsPassport, {"passport", "info"}, True)

            If dsPassport Is Nothing Then
                mErrMessage = DataBase.ErrMessage
                mPassport.IsLogin = False
            Else
                If ErrCode = 0 Then
                    mPassport = CType(JsonConvert.DeserializeObject(JsonConvert.SerializeObject(dsPassport), GetType(PassportInfo)), PassportInfo)
                    mPassport.Init()
                    mPassport.IsLogin = True
                ElseIf ErrCode = -500 Then
                    mPassport.IsLogin = False
                    mErrMessage = DataBase.ErrMessage
                Else
                    mErrMessage = CStr(dsPassport.Tables("passport").Rows(0).Item("ErrMessage"))
                    mPassport.IsLogin = False
                End If

            End If

            dsPassport.Dispose()
            dsPassport = Nothing

        Catch ex As Exception
            mErrMessage = ex.Message
        End Try

        Return ErrCode
    End Function

    Public Sub New(ByVal dsn As String)
        DSNName = dsn
    End Sub
End Class

''' <summary>
''' 通行证信息
''' </summary>
''' <remarks></remarks>
<System.Serializable()> <XmlRoot("T_PASSPORT")> Public Class PassportInfo
    Implements IPassport
    Public passport As Dictionary(Of String, String)()
    Public UserID As Integer                         '用户ID
    Public Token As String                            '用户令牌
    Public IsLogin As Boolean = False                                       '是否登录
    Public Mode As Integer = 0                       '用户身份模式

    Sub Init()
        Mode = GetValueIntByName("F_MODE")
        Token = Item("TOKEN")
        UserID = GetValueIntByName("USERID")
    End Sub


    ''' <summary>
    ''' 属性值
    ''' </summary>
    ''' <param name="Name">属性名</param>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Default ReadOnly Property Item(ByVal Name As String) As String
        Get
            Name = UCase(Name)
            If passport Is Nothing Then
                Return String.Empty
            ElseIf passport(0) Is Nothing Then
                Return String.Empty
            ElseIf Not passport(0).ContainsKey(Name) Then
                Return String.Empty
            Else
                Return passport(0).Item(Name)
            End If
        End Get
    End Property

    ''' <summary>
    ''' 取得属性值(兼容旧函数)
    ''' </summary>
    ''' <param name="Name">取得属性值</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetValueByName(ByVal Name As String) As String
        Return Item(Name)
    End Function

    ''' <summary>
    ''' 取得属性值(整数)
    ''' </summary>
    ''' <param name="Name">名称</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetValueIntByName(ByVal Name As String) As Integer
        Dim s As String = Item(Name)
        If IsNumeric(s) Then
            Return CInt(s)
        Else
            Return 0
        End If
    End Function

    Protected Overrides Sub Finalize()
        MyBase.Finalize()
    End Sub
End Class

<Serializable()> Public Class PassportField
    <XmlElement("Name")> Public Name As String
    <XmlElement("Value")> Public Value As String
End Class
#End Region


#Region "管理员管理"

Enum AdminACL As Short
    ACL_Run = 1
    ACL_Ins = 2
    ACL_Edt = 4
    ACL_Del = 8
    ACL_Upd = 16
    ACL_Qry = 32
    ACL_Prn = 64
End Enum

''' <summary>
''' 管理员管理类
''' </summary>
''' <remarks></remarks>
Public Class AdminManage
    Inherits ClsBase
    Private DSNName As String

    ''' <summary>
    ''' 新建实例
    ''' </summary>
    ''' <param name="dsn">数据连接名称</param>
    ''' <remarks></remarks>
    Public Sub New(ByVal dsn As String)
        DSNName = dsn
    End Sub

    ''' <summary>
    ''' 登录函数,返回代码 1,成功 | 0,失败
    ''' </summary>
    ''' <param name="fnUID">用户名</param>
    ''' <param name="fnPWD">密码</param>
    ''' <param name="fnLoginIP">登录IP</param>
    ''' <returns>管理员实例</returns>
    ''' <remarks></remarks>
    Public Function Login(ByVal fnUID As String, ByVal fnPWD As String, ByVal fnLoginIP As String) As AdminInfo

        Dim DataBase As New Data.DataFactory(DSNName)
        '参数前缀
        Dim prefix As String = CStr(IIf(DataBase.IsMsSql(), "@", ""))

        'LoginID参数定义
        Dim IDPara As System.Data.Common.DbParameter = DataBase.CreateParameter()
        IDPara.ParameterName = String.Concat(prefix, "cAccCode")
        IDPara.Direction = ParameterDirection.Output
        IDPara.DbType = DbType.Int32
        IDPara.Size = 4

        'LoginUID参数定义
        Dim UIDPara As System.Data.Common.DbParameter = DataBase.CreateParameter()
        UIDPara.ParameterName = String.Concat(prefix, "LoginUID")
        UIDPara.DbType = DbType.String
        UIDPara.Value = fnUID

        'LoginPWD参数定义
        Dim PWDPara As System.Data.Common.DbParameter = DataBase.CreateParameter()
        PWDPara.ParameterName = String.Concat(prefix, "LoginPWD")
        PWDPara.DbType = DbType.String
        PWDPara.Value = fnPWD

        'LoginPWD参数定义
        Dim IPPara As System.Data.Common.DbParameter = DataBase.CreateParameter()
        IPPara.ParameterName = String.Concat(prefix, "LoginIP")
        IPPara.DbType = DbType.String
        IPPara.Value = fnLoginIP

        '所有参数数组
        Dim Params As System.Data.Common.DbParameter()
        If DataBase.IsOracle Then
            Dim cursor As New System.Data.OracleClient.OracleParameter
            cursor.ParameterName = "p_cursor"
            cursor.OracleType = OracleClient.OracleType.Cursor
            cursor.Direction = ParameterDirection.Output
            Params = {IDPara, UIDPara, PWDPara, IPPara, cursor}
        Else
            Params = {IDPara, UIDPara, PWDPara, IPPara}
        End If

        Dim ErrCode As Integer

        REM --返回标识 | 0,登录成功 | -1,帐号密码不正确 | -2,禁用 | -3 用户名或密码长度不足
        Dim mAdmin As New AdminInfo
        Try

            Dim dsAdmin As New DataSet("Admin")
            ErrCode = DataBase.ExecuteProduce("[sp_AdminLogin]", Params, dsAdmin, {"master", "rights"}, True)

            If dsAdmin Is Nothing Then
                mErrMessage = DataBase.ErrMessage
                mAdmin.IsLogin = False
            Else
                If ErrCode = 0 Then
                    mAdmin = CType(JsonConvert.DeserializeObject(JsonConvert.SerializeObject(dsAdmin), GetType(AdminInfo)), AdminInfo)
                    mAdmin.IsLogin = True
                ElseIf ErrCode = -500 Then
                    mAdmin.IsLogin = False
                    mErrMessage = DataBase.ErrMessage
                Else
                    mErrMessage = CStr(dsAdmin.Tables("master").Rows(0).Item("ErrMessage"))
                    mAdmin.IsLogin = False
                End If
            End If
        Catch ex As Exception
            mErrMessage = ex.Message
            ErrCode = -100
        End Try

        Return mAdmin
    End Function

End Class



<System.Serializable()> <XmlRoot("SysAcc")> Public Class AdminInfo
    Implements IPassport
    Public master As Dictionary(Of String, String)()
    Public rights As MenuRightsInfo()
    Public IsLogin As Boolean = False              '是否登录

    Public ID As String = getProperty("id")                 '帐号编号
    Public LoginUID As String = String.Empty                '登录用户名
    Public LoginPWD As String = String.Empty                '用户密码(MD5)加密
    Public Status As Integer = 0                            '是否禁用
    Public LoginTimes As Integer = 0                        '登录次数
    Public Description As String = String.Empty             '帐号说明
    Public LastLoginIP As String = String.Empty             '最后登录IP
    Public LastLoginTime As String = String.Empty           '最后登录时间
    Public SecurityLevel As Integer = 0                     '安全等级    
    Public Authorize As String = String.Empty               '数据授权
    Public Token As String = String.Empty                   '令牌
    Private CurrentRight As New MenuRightsInfo

    Private mAcl As Short

    Default ReadOnly Property Item(ByVal Name As String) As String
        Get
            If master Is Nothing Then
                Return String.Empty
            ElseIf master(0) Is Nothing Then
                Return String.Empty
            ElseIf Not master(0).ContainsKey(Name) Then
                Return String.Empty
            Else
                Return master(0).Item(Name)
            End If
        End Get
    End Property

    Public Function getProperty(ByVal Name As String) As String
        Return Item(Name)
    End Function

    Public Function ChkWebRights(ByVal fHtmlFile As String, ByVal fAct As String) As Boolean
        CurrentRight.URL = fHtmlFile
        mAcl = CShort(CInt([Enum].Parse(GetType(AdminACL), fAct, True)))
        Return Array.Exists(rights, AddressOf findWhere)
        'Return True  Rights.Select(String.Format("(url = ""{0}"") and (r & {1}= {1})", fHtmlFile, mAcl)).Length > 0
    End Function

    Public Function ChkWebRights(ByVal MID As Integer, ByVal fAct As String) As Boolean
        mAcl = CShort(CInt([Enum].Parse(GetType(AdminACL), fAct, True)))
        CurrentRight.M = MID
        Return Array.Exists(rights, AddressOf findWhere)
        'Return  Rights.Select(String.Format("(m = {0}) and (r & {1}= {1})", MID, mAcl)).Length > 0
    End Function

    Private Function findWhere(ByVal item As MenuRightsInfo) As Boolean
        Return ((LCase(CurrentRight.URL) = LCase(item.URL) And Not String.IsNullOrEmpty(item.URL)) Or CurrentRight.M = item.M) And ((item.R And mAcl) = mAcl)
    End Function
End Class

Public Class PropertyDict
    Public key As String
    Public value As String
End Class

<System.Serializable()> Public Class MenuRightsInfo
    Public M As Integer = 0
    Public URL As String = String.Empty
    Public R As Integer = 0
End Class

#End Region
''' <summary>
''' IPassport 接口
''' </summary>
''' <remarks></remarks>
Public Interface IPassport

End Interface


'<System.Serializable()> <XmlRoot("T_Passport")> Public Class PassportInfo
'    Implements IPassport
'    Private CurrentName As String

'    Public IsLogin As Boolean = False           '是否登录,由程序修改
'    Public UserID As Integer = 0                '用户ID
'    Public SiteID As Integer = 0                '站点ID
'    Public UserName As String                   '用户名
'    Public PassWord As String                   '用户密码
'    Public State As Integer = -1                '状态（）

'    Public InitModel As Integer = -1            '用户初期模块
'    Public Prpedom As String = ""               '权限模块
'    Public LoginTimes As String = "0"           '登录次数
'    Public LastLoginIP As String                '是否登录IP
'    Public LastLoginTime As String              '最后登录时间
'    Public StateTime As DateTime                '用户开始时间
'    Public StartTime As DateTime                '用户开始时间
'    Public TermTime As DateTime                 '用户到期时间

'    Public AllMoney As String = "0"             '总金额
'    Public AllCredits As String = "0"           '总积分 
'    Public NickName As String = ""              '昵称
'    Public Tel As String = ""                   '总金额
'    Public Email As String = ""                 '用户邮件
'    Public Token As String = ""
'    Public IsLoad As Boolean = False

'    <XmlElement("Fields")> Public Fields() As PassportField

'    REM 查找数组
'    Public Function GetValueByName(ByVal Name As String) As String
'        CurrentName = Name
'        Select Case LCase(Name)
'            Case LCase("userid")
'                Return CStr(UserID)
'            Case LCase("siteid")
'                Return CStr(SiteID)
'            Case LCase("username")
'                Return UserName
'            Case LCase("password")
'                Return PassWord
'            Case LCase("initmodel")
'                Return CStr(InitModel)
'            Case "lastloginip"
'                Return LastLoginIP
'            Case LCase("LastLoginTime")
'                Return LastLoginTime
'            Case LCase("tel")
'                Return Tel
'            Case LCase("termtime")
'                Return CStr(TermTime)
'            Case LCase("AllMoney")
'                Return CStr(AllMoney)
'            Case LCase("AllCredits")
'                Return CStr(AllMoney)
'            Case LCase("NickName")
'                Return CStr(AllMoney)
'            Case LCase("email")
'                Return Email
'            Case LCase("Prpedom")
'                Return Prpedom
'            Case LCase("token")
'                Return Token
'        End Select

'        If Fields Is Nothing OrElse Fields.Length = 0 Then Return String.Empty

'        Dim Field As PassportField = Array.Find(Fields, AddressOf FindWhere)

'        If Field Is Nothing OrElse Field.Value Is Nothing Then Return String.Empty

'        Return Field.Value
'    End Function

'    Private Function FindWhere(ByVal item As PassportField) As Boolean
'        Return item.Name = CurrentName
'    End Function

'    Sub LogOut()
'        IsLogin = False
'        UserID = 0
'        UserName = Nothing
'        PassWord = Nothing
'    End Sub

'    Protected Overrides Sub Finalize()
'        Fields = Nothing
'        MyBase.Finalize()
'    End Sub
'End Class


<System.Serializable()> <XmlRoot()> Public Class DbException
    Public ErrCode As Integer
    Public ErrMessage As String
End Class
